package logic

import (
	"web_app/dao/mysql"
	"web_app/dao/redis"
	"web_app/models"
	"web_app/pkg/snowflake"

	"go.uber.org/zap"
)

func CreatePost(post *models.Post) (err error) {
	post.PostId, err = snowflake.GetID()
	if err != nil {
		return err
	}

	err = mysql.CreatePost(post)
	if err != nil {
		return err
	}
	//将创建的帖子 存入redis key:value -> time:postId
	err = redis.CreatePost(post.PostId, post.CommunityId)
	return
}

//func GetPostById(id uint64) (*models.PostDetail, error) {
//	return mysql.GetPostById(id)
//}

func GetPostDetailById(id uint64) (data *models.ApiPostDetail, err error) {
	//查询并组合我们接口想要的数据
	post, err := mysql.GetPostlById(id)
	if err != nil {
		zap.L().Error("mysql.GetPostDetailById(id) failed", zap.Uint64("post_id", id), zap.Error(err))
		return
	}
	//根据作者id查询作者信息
	user, err := mysql.GetUserById(post.AuthorId)
	if err != nil {
		zap.L().Error("mysql.GetUserById(post.AuthorId) failed",
			zap.Uint64("author_id", post.AuthorId), zap.Error(err))
		return
	}
	//根据社区id查询社区详细信息
	community, err := mysql.GetCommunityDetailById(post.CommunityId)
	if err != nil {
		zap.L().Error("mysql.GetCommunityDetailById(post.CommunityId) failed",
			zap.Int64("community_id", post.CommunityId), zap.Error(err))
		return
	}
	//接口数据拼接
	data = &models.ApiPostDetail{
		AuthorName:      user.Username,
		Post:            post,
		CommunityDetail: community,
	}
	return
}

//贴子 列表
func GetPostList(pagination *models.Pagination) (data []*models.ApiPostDetail, err error) {
	posts, err := mysql.GetPostList(pagination)
	if err != nil {
		return nil, err
	}
	data = make([]*models.ApiPostDetail, 0, len(posts))
	for _, post := range posts {
		//根据作者id查询作者信息
		user, err := mysql.GetUserById(post.AuthorId)
		if err != nil {
			zap.L().Error("mysql.GetUserById(post.AuthorId) failed",
				zap.Uint64("author_id", post.AuthorId), zap.Error(err))
			continue
		}
		//根据社区id查询社区详细信息
		community, err := mysql.GetCommunityDetailById(post.CommunityId)
		if err != nil {
			zap.L().Error("mysql.GetCommunityDetailById(post.CommunityId) failed",
				zap.Int64("community_id", post.CommunityId), zap.Error(err))
			continue
		}
		//接口数据拼接
		postDetail := &models.ApiPostDetail{
			AuthorName:      user.Username,
			Post:            post,
			CommunityDetail: community,
		}
		data = append(data, postDetail)
	}
	return
}

// 新版 查询帖子列表
func GetPostListByParameter(pagination *models.Pagination) (data []*models.ApiPostDetail, err error) {
	//2.去redis查询post_id列表
	idList, err := redis.GetPostIdListInOrder(pagination)
	//fmt.Println(idList)
	if err != nil {
		return
	}
	//redis中查询不到值时
	if len(idList) == 0 {
		zap.L().Warn("redis.GetPostIdListInOrder(pagination) return 0 data")
		return
	}
	zap.L().Debug("GetPostListByParameter", zap.Any("idList", idList))
	//3.根据id去数据库查询帖子详细信息
	//返回的数据还要按照我给定的id的顺序返回
	posts, err := mysql.GetPostListByIdList(idList)
	if err != nil {
		return nil, err
	}
	zap.L().Debug("GetPostListByParameter", zap.Any("posts", posts))
	//提前查询好 每篇帖子的投票数
	voteData, err := redis.GetPostVoteData(idList)
	if err != nil {
		return
	}
	data = make([]*models.ApiPostDetail, 0, len(posts))
	//将帖子的作者及分区信息查询出来填充到帖子中
	for idx, post := range posts {
		//根据作者id查询作者信息
		user, err := mysql.GetUserById(post.AuthorId)
		if err != nil {
			zap.L().Error("mysql.GetUserById(post.AuthorId) failed",
				zap.Uint64("author_id", post.AuthorId), zap.Error(err))
			continue
		}
		//根据社区id查询社区详细信息
		community, err := mysql.GetCommunityDetailById(post.CommunityId)
		if err != nil {
			zap.L().Error("mysql.GetCommunityDetailById(post.CommunityId) failed",
				zap.Int64("community_id", post.CommunityId), zap.Error(err))
			continue
		}
		//接口数据拼接
		postDetail := &models.ApiPostDetail{
			VoteNum:         voteData[idx],
			AuthorName:      user.Username,
			Post:            post,
			CommunityDetail: community,
		}
		data = append(data, postDetail)
	}
	return
}

//根据 指定社区 查询帖子列表
func GetPostListByCommunity(cp *models.Pagination) (data []*models.ApiPostDetail, err error) {
	//2.去redis查询post_id列表
	idList, err := redis.GetPostIdListInCommunityId(cp)
	//fmt.Println(idList)
	if err != nil {
		return
	}
	//redis中查询不到值时
	if len(idList) == 0 {
		zap.L().Warn("redis.GetPostIdListInOrder(cp) return 0 data")
		return
	}
	zap.L().Debug("GetPostListByParameter", zap.Any("idList", idList))
	//3.根据id去数据库查询帖子详细信息
	//返回的数据还要按照我给定的id的顺序返回
	posts, err := mysql.GetPostListByIdList(idList)
	if err != nil {
		return nil, err
	}
	zap.L().Debug("GetPostListByParameter", zap.Any("posts", posts))
	//提前查询好 每篇帖子的投票数
	voteData, err := redis.GetPostVoteData(idList)
	if err != nil {
		return
	}
	data = make([]*models.ApiPostDetail, 0, len(posts))
	//将帖子的作者及分区信息查询出来填充到帖子中
	for idx, post := range posts {
		//根据作者id查询作者信息
		user, err := mysql.GetUserById(post.AuthorId)
		if err != nil {
			zap.L().Error("mysql.GetUserById(post.AuthorId) failed",
				zap.Uint64("author_id", post.AuthorId), zap.Error(err))
			continue
		}
		//根据社区id查询社区详细信息
		community, err := mysql.GetCommunityDetailById(post.CommunityId)
		if err != nil {
			zap.L().Error("mysql.GetCommunityDetailById(post.CommunityId) failed",
				zap.Int64("community_id", post.CommunityId), zap.Error(err))
			continue
		}
		//接口数据拼接
		postDetail := &models.ApiPostDetail{
			VoteNum:         voteData[idx],
			AuthorName:      user.Username,
			Post:            post,
			CommunityDetail: community,
		}
		data = append(data, postDetail)
	}
	return
}

func HasCommunityId(p *models.Pagination) (data []*models.ApiPostDetail, err error) {
	if p.CommunityId == 0 {
		//没有社区id参数
		data, err = GetPostListByParameter(p)
	} else {
		//有社区id参数
		data, err = GetPostListByCommunity(p)
	}
	if err != nil {
		zap.L().Error("HasCommunityId", zap.Error(err))
		return nil, err
	}
	return
}
